; timer.asm
; Timer handling

	.include "common.inc"
	.include "vicrom.inc"
	.include "disk.inc"
	.include "string.inc"

	.export init_timer
	.export timer_irq
	.export do_timer
	.export get_time
	.export get_timestr
	.export wait_refresh
	.export set_1s_fun
	.export timer_run
	.export notify_activity
	.export set_actfun
	.export clr_timer

NTSC_TIMER_VALUE =	261 * 65 - 2
PAL_TIMER_VALUE = 	312 * 71 - 2		; Original: $4826

PAL_TPS		= 50
NTSC_TPS	= 60

NTSC_LINE = $75		; raster line 234/235
PAL_LINE = $90		; raster line 288/289

	.segment "DATA"

tps:		.byte $00

ticks:		.byte $00

seconds:	.byte $00
minutes:	.byte $00
hours:		.byte $00

tick_1s:	.byte $00

vsync_flg:	.byte $00
active_flg:	.byte $00

	.segment "JMPTABLE"

tick_1s_handler:
			.word nopfun
			
activity_handler:
			.word nopfun

	.segment "BOOT"

; Placeholder, TODO: implementation

init_timer:	jsr readrtc	
			bcs @deftime
			eor #$FF
			sec
			adc #24
			sta hours
			txa
			eor #$FF
			sec
			adc #60
			sta minutes
			tya
			eor #$FF
			sec
			adc #60
			sta seconds
			jmp @skptime
@deftime:	lda #60
			sta seconds
			sta minutes
			lda #24
			sta hours
@skptime:	lda #0
			sta tick_1s
			sta vsync_flg
			sta active_flg
			lda MACHINE			; machine detection by r.hurst
			cmp #M_NTSC
			beq ntsc
			cmp #M_PAL
			beq pal
			jmp panic
ntsc:		lda #NTSC_TPS
			sta tps
			sta ticks
			lda #<NTSC_TIMER_VALUE
			sta $9124
			ldx #>NTSC_TIMER_VALUE
			lda #NTSC_LINE
			bne irqsync
pal:		lda #PAL_TPS
			sta tps
			sta ticks
			lda #<PAL_TIMER_VALUE
			sta $9124
			ldx #>PAL_TIMER_VALUE
			lda #PAL_LINE
			bne irqsync
irqsync:	cmp VIC_BASE+$04
			bne irqsync
			stx $9125		; load T1 latch high, and transfer both bytes to T1 counter
			rts

	.segment "CODE"

timer_irq:	dec ticks
			bne @done_inc
			lda tps
			sta ticks
			inc tick_1s
			dec seconds
			bne @done_inc
			ldx #60
			stx seconds
			dec minutes
			bne @done_inc
			stx minutes
			dec hours
			bne @done_inc
			lda #24
			sta hours
@done_inc:	lda vsync_flg
			beq @done_sync
			dec vsync_flg
@done_sync:
			rts

timer_run:	lda #1
			sta active_flg
			rts

do_timer:	lda tick_1s
			beq @done
			dec tick_1s
			jmp (tick_1s_handler) 
@done:		rts

clr_timer:	lda #0
			sta tick_1s

nopfun:		rts

get_time:	; return current time in A..sec/X..min/Y..hour
			lda #24
			sec
			sei
			sbc hours
			tay
			lda #60
			sec
			sbc minutes
			tax
			lda #60
			sec
			sbc seconds
			cli
			rts

get_timestr:
			jsr get_time
			pha
			txa
			pha
			tya
			jsr add2num
			lda #':'
			jsr saddch
			pla
			jsr add2num
			lda #':'
			jsr saddch
			pla
			jmp add2num

add2num:	cmp #10
			bcs @ntrl
			pha
			lda #'0'
			jsr saddch
			pla
@ntrl:		ldx #0
			jmp sputuint

wait_refresh:
			lda active_flg
			beq @done
			; wait for vertical retrace
			lda #1
			sta vsync_flg
@pollwait:	cmp vsync_flg
			beq @pollwait
@done:		rts

set_1s_fun:	sta tick_1s_handler
			stx tick_1s_handler+1
			rts

set_actfun:	sta activity_handler
			stx activity_handler+1
			rts

;
;	Notify of user input (for inactivity timer)
;

notify_activity:
			jmp (activity_handler)
